package domain;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

import util.DateUtil;

@Entity
public class Schedule implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	@Id @GeneratedValue
	private long id;
	private Timestamp date;
	private Timestamp startTime;
	private Timestamp endTime;
	@Enumerated(EnumType.STRING)
	private Route route;
	
	@Enumerated(EnumType.STRING)
	private ScheduleStatus status;
	
	private Timestamp prioritizedTime;
	
	@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)
	private List<Mission> missions = new ArrayList<Mission>();
	
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public Route getRoute() {
		return route;
	}
	public void setRoute(Route route) {
		this.route = route;
	}
	public List<Mission> getMissions() {
		return missions;
	}
	public void addMission(Mission s){
		missions.add(s);
	}
	public ScheduleStatus getStatus() {
		return status;
	}
	public void setStatus(ScheduleStatus status) {
		this.status = status;
	}
	public Timestamp getStartTime() {
		return startTime;
	}
	public void setStartTime(Timestamp startTime) {
		this.startTime = startTime;
	}
	public Timestamp getEndTime() {
		return endTime;
	}
	public void setEndTime(Timestamp endTime) {
		this.endTime = endTime;
	}
	public Timestamp getPrioritizedTime() {
		return prioritizedTime;
	}
	public void setPrioritizedTime(Timestamp prioritizedTime) {
		this.prioritizedTime = prioritizedTime;
	}
	public Timestamp getDate() {
		return date;
	}
	public void setDate(Timestamp date) {
		this.date = date;
	}
	
	
	//Domain Logic
	public List<POS> getPrioritizedPOS(){
		List<POS> posList = new ArrayList<POS>();
		sortMisionsByPriority();
			for(int i=0; i<missions.size(); i++){
				Mission mission = missions.get(i);
				System.out.println(mission.getFromPOS().getName());
				if(i==0){
					POS fromPos = mission.getFromPOS();
					POS toPos = mission.getToPOS();
					posList.add(fromPos);
					posList.add(toPos);
				}else{
					POS toPos = mission.getToPOS();
					posList.add(toPos);
				}
			}
		return posList;
	}
	
	public void sortMisionsByPriority(){
		List<Mission> missionList = new ArrayList<Mission>();
		
		for (int i=0; i<missions.size(); i++){
			for (int j=0; j<missions.size(); j++){
				Mission mission = missions.get(j);
				if(mission.getPriority()==i+1){
					missionList.add(mission);
					break;
				}
			}
	    }
		
		missions = missionList;
	}
	
	public boolean isReachDuedDate(){
		boolean reach = false;
			if(DateUtil.getDiffDays(DateUtil.getDDMMYYYYFromTimestamp(this.date), DateUtil.getCurrentDDMMYYYY_CE())>=0){
				reach = true;
			}
		return reach;
	}
	
	public boolean isItPassedSchedule(){
		boolean passed = false;
		if(DateUtil.getDiffDays(DateUtil.getDDMMYYYYFromTimestamp(this.date), DateUtil.getCurrentDDMMYYYY_CE())>0){
			passed = true;
		}
		return passed;
	}
	
	public int getNoOfCompletedMissions(){
		int count=0;
		for (int i=0; i<missions.size(); i++){
			Mission mission = missions.get(i);
			if(mission.getStatus().equals(MissionStatus.complete)){
				count++;
			}
	    }
		return count;
	}
	
	public int getNoOfAllMissions(){
		return missions.size();
	}
	
	public boolean isCompleted(){
		int complete = this.getNoOfCompletedMissions();
		int all = this.getNoOfAllMissions();
		
		if(complete==all)
			return true;
		else
			return false;
	}
	
	public void checkAndUpdateCompleteStatus(){
		if(isCompleted()){
			this.status = ScheduleStatus.completed;
		}
	}
	
	public void updateCompleteMission(int missionId){
		List<Mission> missions = this.missions;
		Mission mission = null;
		for(int i=0; i<missions.size(); i++){
			mission = missions.get(i);
			if(mission.getId()==missionId){
				mission.updateCompelteStatus();
				break;
			}
		}
	}
	
	public void updatePriorityAndFromPOS(POS fromPOS, POS toPOS, int pri){
		for(Mission m : missions){
			if(m.getToPOS().getId() == toPOS.getId()){
				m.setFromPOS(fromPOS);
				m.setPriority(pri);
			}
		}
		
	}
	
	public List<POS> getUnPrioritizePOS(){
		List<POS> posList = new ArrayList<POS>();
			for(int i=0; i<missions.size(); i++){
				Mission mission = missions.get(i);
					POS toPos = mission.getToPOS();
					posList.add(toPos);
			}
		return posList;
	}
}

